from django.shortcuts import render, redirect
from django.contrib.auth.decorators import login_required
from django.db import connection
from django.contrib import messages
from django.utils import timezone
import random
import base64
from utilities.db_utils import dictfetchall
import qrcode
import io
from django.http import HttpResponse, JsonResponse
from PIL import Image, ImageDraw
from django.views.decorators.csrf import csrf_exempt
import os
from django.conf import settings

# Create your views here.

@login_required
def order_list(request):
    """用户订单列表视图"""
    user_id = request.user.user_id
    
    # 获取用户的所有订单
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT order_id, order_no, total_amount, status, create_time, update_time
            FROM tb_order
            WHERE user_id = %s
            ORDER BY create_time DESC
        """, [user_id])
        
        orders = dictfetchall(cursor)
    
    return render(request, 'order/list.html', {
        'title': '我的订单',
        'orders': orders
    })

@login_required
def order_detail(request, order_id):
    """订单详情视图"""
    user_id = request.user.user_id
    context = {
        'title': '订单详情'
    }
    
    # 获取订单基本信息
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT order_id, order_no, total_amount, status, create_time, update_time
            FROM tb_order
            WHERE order_id = %s AND user_id = %s
        """, [order_id, user_id])
        
        order = cursor.fetchone()
        if not order:
            # 如果订单不存在或不属于当前用户，返回订单列表
            return redirect('order:list')
        
        # 将订单信息转换为字典
        order_info = {
            'order_id': order[0],
            'order_no': order[1],
            'total_amount': order[2],
            'status': order[3],
            'create_time': order[4],
            'update_time': order[5]
        }
        
        # 获取订单商品 - 同时查询是否已开盒
        cursor.execute("""
            SELECT oi.item_id, oi.box_id, oi.quantity, oi.price,
                   bb.name, bb.image_url, oi.drawn
            FROM tb_order_item oi
            JOIN tb_blind_box bb ON oi.box_id = bb.box_id
            WHERE oi.order_id = %s
        """, [order_id])
        
        order_items = dictfetchall(cursor)
        
        # 计算每个商品的小计金额
        for item in order_items:
            item['item_total'] = item['quantity'] * item['price']
        
        context['order'] = order_info
        context['order_items'] = order_items
    
    return render(request, 'order/detail.html', context)

@login_required
@csrf_exempt
def pay_order_ajax(request, order_id):
    """通过AJAX方式支付订单，不进行页面跳转"""
    if request.method != 'POST':
        return JsonResponse({'success': False, 'message': '请求方法错误'}, status=400)
    
    user_id = request.user.user_id
    
    # 验证订单是否属于当前用户且状态为待支付
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT order_id, total_amount
            FROM tb_order
            WHERE order_id = %s AND user_id = %s AND status = 1
        """, [order_id, user_id])
        
        order = cursor.fetchone()
        if not order:
            return JsonResponse({'success': False, 'message': '订单不存在或不是待支付状态'}, status=404)
        
        # 这里是模拟支付成功的逻辑
        try:
            # 更新订单状态为待发货
            cursor.execute("""
                UPDATE tb_order
                SET status = 2, update_time = %s
                WHERE order_id = %s
            """, [timezone.now(), order_id])
            
            return JsonResponse({'success': True, 'message': '支付成功，订单已更新为待发货状态'})
        except Exception as e:
            return JsonResponse({'success': False, 'message': f'支付处理失败：{str(e)}'}, status=500)

@login_required
def cancel_order(request, order_id):
    """取消订单"""
    if request.method != 'POST':
        return redirect('order:detail', order_id=order_id)
    
    user_id = request.user.user_id
    
    # 验证订单是否属于当前用户且状态为待支付
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT order_id
            FROM tb_order
            WHERE order_id = %s AND user_id = %s AND status = 1
        """, [order_id, user_id])
        
        if not cursor.fetchone():
            messages.error(request, '只能取消待支付的订单')
            return redirect('order:detail', order_id=order_id)
        
        try:
            # 更新订单状态为已取消
            cursor.execute("""
                UPDATE tb_order
                SET status = 5, update_time = %s
                WHERE order_id = %s
            """, [timezone.now(), order_id])
            
            # 恢复库存 - 修复SQL语法，FROM位置不正确
            cursor.execute("""
                UPDATE tb_blind_box bb
                JOIN tb_order_item oi ON oi.box_id = bb.box_id
                SET bb.stock = bb.stock + oi.quantity
                WHERE oi.order_id = %s
            """, [order_id])
            
            messages.success(request, '订单已取消')
        except Exception as e:
            messages.error(request, f'取消订单失败：{str(e)}')
    
    return redirect('order:detail', order_id=order_id)

@login_required
def complete_order(request, order_id):
    """确认收货，完成订单"""
    if request.method != 'POST':
        return redirect('order:detail', order_id=order_id)
    
    user_id = request.user.user_id
    
    # 验证订单是否属于当前用户且状态为已发货
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT order_id
            FROM tb_order
            WHERE order_id = %s AND user_id = %s AND status = 3
        """, [order_id, user_id])
        
        if not cursor.fetchone():
            messages.error(request, '只能确认已发货的订单')
            return redirect('order:detail', order_id=order_id)
        
        try:
            # 更新订单状态为已完成
            cursor.execute("""
                UPDATE tb_order
                SET status = 4, update_time = %s
                WHERE order_id = %s
            """, [timezone.now(), order_id])
            
            messages.success(request, '订单已完成，感谢您的购买！')
        except Exception as e:
            messages.error(request, f'确认收货失败：{str(e)}')
    
    return redirect('order:detail', order_id=order_id)

@login_required
def draw_box(request, order_id, item_id):
    """开盲盒功能 - 在订单完成后查看盲盒内容"""
    user_id = request.user.user_id
    
    # 验证订单是否属于当前用户且已完成
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT o.order_id, oi.box_id, oi.drawn, o.qr_code
            FROM tb_order o
            JOIN tb_order_item oi ON o.order_id = oi.order_id
            WHERE o.order_id = %s AND o.user_id = %s AND oi.item_id = %s
            AND o.status IN (3, 4)  # 已发货或已完成状态
        """, [order_id, user_id, item_id])
        
        order_item = cursor.fetchone()
        if not order_item:
            messages.error(request, '订单不存在或不是已完成状态，无法开盒')
            return redirect('order:detail', order_id=order_id)
        
        # 检查是否已经开过盒
        if order_item[2]:  # drawn字段为True表示已开盒
            # 直接获取已开盒的结果
            cursor.execute("""
                SELECT dr.product_id, p.name, p.image_url, p.original_price, p.category, p.brand
                FROM draw_record dr
                JOIN tb_product p ON dr.product_id = p.product_id
                WHERE dr.user_id = %s AND dr.box_id = %s AND dr.order_item_id = %s
            """, [user_id, order_item[1], item_id])
            
            drawn_product = cursor.fetchone()
            if drawn_product:
                product = {
                    'product_id': drawn_product[0],
                    'name': drawn_product[1],
                    'image_url': drawn_product[2],
                    'original_price': drawn_product[3],
                    'category': drawn_product[4],
                    'brand': drawn_product[5]
                }
            else:
                messages.error(request, '未找到开盒记录')
                return redirect('order:detail', order_id=order_id)
        else:
            # 还未开盒，获取盲盒内容并随机抽取
            cursor.execute("""
                SELECT bc.content_id, bc.product_id, p.name, p.image_url, p.original_price, p.category, p.brand
                FROM tb_box_content bc
                JOIN tb_product p ON bc.product_id = p.product_id
                WHERE bc.box_id = %s
            """, [order_item[1]])
            
            contents = cursor.fetchall()
            if not contents:
                messages.error(request, '该盲盒暂无内容配置')
                return redirect('order:detail', order_id=order_id)
            
            # 随机选择一个内容
            drawn_content = random.choice(contents)
            product = {
                'product_id': drawn_content[1],
                'name': drawn_content[2],
                'image_url': drawn_content[3],
                'original_price': drawn_content[4],
                'category': drawn_content[5],
                'brand': drawn_content[6]
            }
            
            # 记录抽盒结果
            now = timezone.now()
            cursor.execute("""
                INSERT INTO draw_record (user_id, box_id, product_id, order_id, order_item_id, create_time)
                VALUES (%s, %s, %s, %s, %s, %s)
            """, [user_id, order_item[1], product['product_id'], order_id, item_id, now])
            
            # 更新订单项为已开盒
            cursor.execute("""
                UPDATE tb_order_item
                SET drawn = TRUE
                WHERE item_id = %s
            """, [item_id])
        
        # 获取盲盒和超市信息
        cursor.execute("""
            SELECT bb.name, bb.image_url, bb.original_price, bb.discount_price,
                   sm.market_id, sm.name as market_name, sm.address as market_address,
                   sm.longitude, sm.latitude, sm.phone as market_phone,
                   sm.business_hours
            FROM tb_blind_box bb
            LEFT JOIN tb_supermarket sm ON bb.market_id = sm.market_id
            WHERE bb.box_id = %s
        """, [order_item[1]])
        
        box_info = cursor.fetchone()
        if not box_info:
            messages.error(request, '未找到盲盒信息')
            return redirect('order:detail', order_id=order_id)
        
        box = {
            'name': box_info[0],
            'image_url': box_info[1],
            'original_price': box_info[2],
            'discount_price': box_info[3]
        }
        
        # 超市信息
        market = None
        if box_info[4]:  # 如果有超市ID
            market = {
                'market_id': box_info[4],
                'name': box_info[5],
                'address': box_info[6],
                'longitude': float(box_info[7]) if box_info[7] else None,
                'latitude': float(box_info[8]) if box_info[8] else None,
                'phone': box_info[9],
                'business_hours': box_info[10]
            }
        
        # 获取或生成二维码
        qr_code_url = order_item[3]  # 从查询结果中获取订单的二维码URL
        
        # 如果没有二维码，生成并保存
        if not qr_code_url:
            try:
                # 生成取货码数据
                pickup_code = ''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=12))
                pickup_data = f"PICKUP_{order_id}_{item_id}_{pickup_code}_{timezone.now().strftime('%Y%m%d%H%M%S')}"
                
                # 生成二维码
                qr = qrcode.QRCode(
                    version=1,
                    error_correction=qrcode.constants.ERROR_CORRECT_L,
                    box_size=10,
                    border=4,
                )
                qr.add_data(pickup_data)  # 使用新生成的取货码数据
                qr.make(fit=True)
                
                img = qr.make_image(fill_color="black", back_color="white")
                
                # 添加中心标记
                # 使用绿色作为中心标记颜色
                color = "#07c160"  # 使用十六进制表示绿色
                
                # 在二维码中间绘制一个彩色方块
                draw = ImageDraw.Draw(img)
                img_width, img_height = img.size
                center_size = img_width // 10
                center_pos = (img_width // 2 - center_size // 2, img_height // 2 - center_size // 2)
                draw.rectangle(
                    [center_pos, (center_pos[0] + center_size, center_pos[1] + center_size)],
                    fill=color
                )
                
                # 确保目录存在
                qrcode_dir = os.path.join(settings.MEDIA_ROOT, 'qrcodes')
                os.makedirs(qrcode_dir, exist_ok=True)
                
                # 生成唯一文件名
                filename = f"pickup_{order_id}_{item_id}_{pickup_code}.png"
                filepath = os.path.join(qrcode_dir, filename)
                
                # 保存图片到文件
                img.save(filepath, format="PNG")
                
                # 存储文件的URL路径而不是Base64数据
                qr_code_url = f"{settings.MEDIA_URL}qrcodes/{filename}"
                
                # 更新二维码URL到数据库
                cursor.execute("""
                    UPDATE tb_order
                    SET qr_code = %s
                    WHERE order_id = %s
                """, [qr_code_url, order_id])
                
                messages.success(request, '已成功生成取货二维码')
            except Exception as e:
                # 记录错误信息，但不中断流程
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"生成二维码失败: {str(e)}")
                messages.warning(request, f'二维码生成失败，请联系客服。错误: {str(e)}')
                qr_code_url = None
    
    # 返回开盒结果页面
    context = {
        'title': '开盒结果',
        'box': box,
        'product': product,
        'market': market,
        'order_id': order_id,
        'saved_amount': float(box.get('original_price', 0)) - float(box.get('discount_price', 0)),
        'qr_code_url': qr_code_url,
        'is_view_result': False,  # 标记这是直接开盒，需要显示动画
        'debug_info': {
            'has_qrcode': qr_code_url is not None,
            'qr_path': qr_code_url if qr_code_url else '未生成',
        }
    }
    return render(request, 'order/draw_result.html', context)

@login_required
def my_boxes(request):
    """我的盲盒列表视图 - 只显示已完成订单的盲盒"""
    user_id = request.user.user_id
    
    # 获取用户已完成订单的所有盲盒
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT oi.item_id, oi.box_id, oi.quantity, oi.price, oi.drawn,
                   bb.name, bb.image_url, bb.category, bb.description,
                   o.order_id, o.order_no, o.create_time
            FROM tb_order o
            JOIN tb_order_item oi ON o.order_id = oi.order_id
            JOIN tb_blind_box bb ON oi.box_id = bb.box_id
            WHERE o.user_id = %s AND o.status IN (3, 4)
            ORDER BY o.create_time DESC
        """, [user_id])
        
        boxes = dictfetchall(cursor)
    
    return render(request, 'order/my_boxes.html', {
        'title': '我的盲盒',
        'boxes': boxes
    })

@login_required
def view_draw_result(request, order_id, item_id):
    """查看已开盒的结果"""
    user_id = request.user.user_id
    
    # 验证订单是否属于当前用户
    with connection.cursor() as cursor:
        # 获取开盒记录，包括超市信息
        cursor.execute("""
            SELECT dr.product_id, p.name, p.image_url, p.original_price, p.category, p.brand,
                   bb.name as box_name, bb.image_url as box_image_url, bb.original_price as box_original_price,
                   bb.discount_price as box_discount_price, o.qr_code,
                   sm.market_id, sm.name as market_name, sm.address as market_address,
                   sm.longitude, sm.latitude, sm.phone as market_phone,
                   sm.business_hours
            FROM draw_record dr
            JOIN tb_product p ON dr.product_id = p.product_id
            JOIN tb_blind_box bb ON dr.box_id = bb.box_id
            JOIN tb_order o ON dr.order_id = o.order_id
            LEFT JOIN tb_supermarket sm ON bb.market_id = sm.market_id
            WHERE dr.user_id = %s AND dr.order_id = %s AND dr.order_item_id = %s
        """, [user_id, order_id, item_id])
        
        result = cursor.fetchone()
        if not result:
            messages.error(request, '未找到开盒记录')
            return redirect('order:my_boxes')
        
        product = {
            'product_id': result[0],
            'name': result[1],
            'image_url': result[2],
            'original_price': result[3],
            'category': result[4],
            'brand': result[5]
        }
        
        box = {
            'name': result[6],
            'image_url': result[7],
            'original_price': result[8],
            'discount_price': result[9]
        }
        
        # 超市信息
        market = None
        if result[11]:  # 如果有超市ID
            market = {
                'market_id': result[11],
                'name': result[12],
                'address': result[13],
                'longitude': float(result[14]) if result[14] else None,
                'latitude': float(result[15]) if result[15] else None,
                'phone': result[16],
                'business_hours': result[17]
            }
        
        # 检查是否已有二维码
        qr_code_url = result[10]
        
        # 如果没有二维码，生成并保存
        if not qr_code_url:
            try:
                # 生成取货码数据
                pickup_code = ''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=12))
                pickup_data = f"PICKUP_{order_id}_{item_id}_{pickup_code}_{timezone.now().strftime('%Y%m%d%H%M%S')}"
                
                # 生成二维码
                qr = qrcode.QRCode(
                    version=1,
                    error_correction=qrcode.constants.ERROR_CORRECT_L,
                    box_size=10,
                    border=4,
                )
                qr.add_data(pickup_data)  # 使用新生成的取货码数据
                qr.make(fit=True)
                
                img = qr.make_image(fill_color="black", back_color="white")
                
                # 添加中心标记
                # 使用绿色作为中心标记颜色
                color = "#07c160"  # 使用十六进制表示绿色
                
                # 在二维码中间绘制一个彩色方块
                draw = ImageDraw.Draw(img)
                img_width, img_height = img.size
                center_size = img_width // 10
                center_pos = (img_width // 2 - center_size // 2, img_height // 2 - center_size // 2)
                draw.rectangle(
                    [center_pos, (center_pos[0] + center_size, center_pos[1] + center_size)],
                    fill=color
                )
                
                # 确保目录存在
                qrcode_dir = os.path.join(settings.MEDIA_ROOT, 'qrcodes')
                os.makedirs(qrcode_dir, exist_ok=True)
                
                # 生成唯一文件名
                filename = f"pickup_{order_id}_{item_id}_{pickup_code}.png"
                filepath = os.path.join(qrcode_dir, filename)
                
                # 保存图片到文件
                img.save(filepath, format="PNG")
                
                # 存储文件的URL路径而不是Base64数据
                qr_code_url = f"{settings.MEDIA_URL}qrcodes/{filename}"
                
                # 更新二维码URL到数据库
                cursor.execute("""
                    UPDATE tb_order
                    SET qr_code = %s
                    WHERE order_id = %s
                """, [qr_code_url, order_id])
                
                messages.success(request, '已成功生成取货二维码')
            except Exception as e:
                # 记录错误信息，但不中断流程
                import logging
                logger = logging.getLogger(__name__)
                logger.error(f"生成二维码失败: {str(e)}")
                messages.warning(request, f'二维码生成失败，请联系客服。错误: {str(e)}')
                qr_code_url = None
    
    # 返回开盒结果页面
    context = {
        'title': '开盒结果',
        'box': box,
        'product': product,
        'market': market,
        'order_id': order_id,
        'saved_amount': float(box.get('original_price', 0)) - float(box.get('discount_price', 0)),
        'qr_code_url': qr_code_url,
        'is_view_result': True,  # 标记这是查看已开盒结果，不需要显示动画
        'debug_info': {
            'has_qrcode': qr_code_url is not None,
            'qr_path': qr_code_url if qr_code_url else '未生成',
        }
    }
    return render(request, 'order/draw_result.html', context)

@login_required
def generate_qrcode(request):
    """生成支付用的二维码"""
    method = request.GET.get('method', 'wechat')
    amount = request.GET.get('amount', '0.00')
    code = request.GET.get('code', '')  # 获取随机生成的支付码
    
    # 如果没有提供支付码，生成一个
    if not code:
        code = ''.join(random.choices('ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789', k=16))
    
    # 创建支付数据
    payment_data = f"{method.upper()}_PAY_{amount}_YUAN_CODE_{code}_TIME_{timezone.now().strftime('%Y%m%d%H%M%S')}"
    
    # 创建二维码
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_L,
        box_size=10,
        border=4,
    )
    qr.add_data(payment_data)
    qr.make(fit=True)
    
    # 创建图片
    img = qr.make_image(fill_color="black", back_color="white")
    
    # 添加支付方式的标志
    if method == 'wechat':
        # 微信绿色
        color = "#07c160"  # 使用十六进制表示绿色
    else:
        # 支付宝蓝色
        color = "#1677ff"  # 使用十六进制表示蓝色
    
    # 在二维码中间绘制一个彩色方块
    draw = ImageDraw.Draw(img)
    img_width, img_height = img.size
    center_size = img_width // 10
    center_pos = (img_width // 2 - center_size // 2, img_height // 2 - center_size // 2)
    draw.rectangle(
        [center_pos, (center_pos[0] + center_size, center_pos[1] + center_size)],
        fill=color
    )
    
    # 检查是否为AJAX请求
    is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' or 'json' in request.GET
    
    if is_ajax:
        # 将图片保存为临时文件并返回URL
        qrcode_dir = os.path.join(settings.MEDIA_ROOT, 'qrcodes', 'payment')
        os.makedirs(qrcode_dir, exist_ok=True)
        
        # 生成唯一文件名
        timestamp = timezone.now().strftime('%Y%m%d%H%M%S')
        filename = f"payment_{method}_{code}_{timestamp}.png"
        filepath = os.path.join(qrcode_dir, filename)
        
        # 保存图片到文件
        img.save(filepath, format="PNG")
        
        # 返回文件URL
        image_url = f"{settings.MEDIA_URL}qrcodes/payment/{filename}"
        return JsonResponse({
            'success': True,
            'image_data': image_url,
            'payment_code': code
        })
    else:
        # 直接返回图片
        buffer = io.BytesIO()
        img.save(buffer, format="PNG")
        buffer.seek(0)
        return HttpResponse(buffer, content_type='image/png')

@login_required
def pay_order(request, order_id):
    """支付订单（已弃用，请使用AJAX接口代替）"""
    user_id = request.user.user_id
    
    # 添加警告消息
    messages.warning(request, '您正在使用旧版支付接口，建议使用新的AJAX支付方式')
    
    # 验证订单是否属于当前用户且状态为待支付
    with connection.cursor() as cursor:
        cursor.execute("""
            SELECT order_id, total_amount
            FROM tb_order
            WHERE order_id = %s AND user_id = %s AND status = 1
        """, [order_id, user_id])
        
        order = cursor.fetchone()
        if not order:
            messages.error(request, '订单不存在或不是待支付状态')
            return redirect('order:list')
        
        # 这里应该有实际的支付逻辑
        # 模拟支付成功
        try:
            # 更新订单状态为待发货
            cursor.execute("""
                UPDATE tb_order
                SET status = 2, update_time = %s
                WHERE order_id = %s
            """, [timezone.now(), order_id])
            
            messages.success(request, '支付成功，订单已更新为待发货状态')
        except Exception as e:
            messages.error(request, f'支付处理失败：{str(e)}')
    
    return redirect('order:detail', order_id=order_id)
